#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "delay.h"
#include "AT24C02.h"
#include "timer0.h"
#include "key.h"

#define T_OVER_HIGH  "OV:H"
#define T_OVER_LOW   "OV:L"
#define T_OVER_BLANK "    "
#define T_HIGH_MAX  125
#define T_LOW_MIN   -55
#define T_HIGH_DEFAULT  20
#define T_LOW_DEFAULT   15

float T, T_SHOW;
unsigned char keyNumber;
unsigned char THigh, TLow;

void main()
{
	THigh = AT24C02_readByte(0);
	TLow = AT24C02_readByte(1);
	// 若THigh和TLow取出的值不合规，则使用默认值
	if(THigh > T_HIGH_MAX || TLow < T_LOW_MIN || THigh <= TLow)
	{
		THigh = T_HIGH_DEFAULT;
		TLow = T_LOW_DEFAULT;
	}
	
	// 先转换温度，防止出现默认值
	DS18B20_convertT();
	delay(1000);
	LCD_Init();
	LCD_ShowString(1, 1, "T:");
	LCD_ShowString(2, 1, "TH:");
	LCD_ShowSignedNum(2, 4, THigh, 3);
	LCD_ShowString(2, 9, "TL:");
	LCD_ShowSignedNum(2, 12, TLow, 3);
	timer0_init();
	
	while(1)
	{
		// 转换温度
		DS18B20_convertT();
		// 读取温度
		T = DS18B20_readT();
		// 若温度小于0
		if(T < 0)
		{
			LCD_ShowString(1, 3, "-");
			// 将温度变为正数
			T_SHOW = -T;
		}
		// 若温度大于等于0
		else
		{
			LCD_ShowString(1, 3, "+");
			T_SHOW = T;
		}
		// 显示整数部分
		LCD_ShowNum(1, 4, T_SHOW, 3);
		LCD_ShowString(1, 7, ".");
		// 显示小数部分（先扩大10000倍，再取模10000）
		LCD_ShowNum(1, 8, (unsigned long)(T_SHOW*10000)%10000, 4);
		
		keyNumber = getKey();
		// 若键盘被按下
		if(keyNumber)
		{
			// 按键1被按下
			if(keyNumber == 1)
			{
				THigh++;
				if(THigh > T_HIGH_MAX)
				{
					THigh = T_HIGH_MAX;
				}
			}
			// 按键2被按下
			else if(keyNumber == 2)
			{
				THigh--;
				if(THigh <= TLow)
				{
					THigh++;
				}
			}
			// 按键3被按下
			if(keyNumber == 3)
			{
				TLow++;
				if(TLow >= THigh)
				{
					TLow--;
				}
			}
			// 按键4被按下
			else if(keyNumber == 4)
			{
				TLow--;
				if(TLow < T_LOW_MIN)
				{
					TLow = T_LOW_MIN;
				}
			}
			LCD_ShowSignedNum(2, 4, THigh, 3);
			LCD_ShowSignedNum(2, 12, TLow, 3);
			// 温控值写到AT24C02中
			AT24C02_writeByte(0, THigh);
			delay(5);
			AT24C02_writeByte(1, TLow);
			delay(5);
		}
		
		// 温度报警输出
		if(T > THigh)
		{
			LCD_ShowString(1, 13, T_OVER_HIGH);
		}
		else if(T < TLow)
		{
			LCD_ShowString(1, 13, T_OVER_LOW);
		}
		else
		{
			LCD_ShowString(1, 13, T_OVER_BLANK);
		}
	}
}

void Time0_Rountine() interrupt 1
{
	static unsigned int t0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	
	t0Count++; //t0Count计次，对中断频率进行分频
	// 分频20次，大于20ms，计数器重置为0
	if(t0Count >= 20)
	{
		t0Count = 0;
		key_loop();
	}
}